package com.sharer.last.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sharer.last.base.enums.BusinessExceptionCode;
import com.sharer.last.base.enums.ExceptionPrefixParamEnum;
import com.sharer.last.base.exception.BusinessException;
import com.sharer.last.base.model.PageVO;
import com.sharer.last.base.support.QueryCondition;
import com.sharer.last.base.utils.CollectionUtil;
import com.sharer.last.base.utils.ConvertUtil;
import com.sharer.last.base.utils.StringUtil;
import com.sharer.last.mapper.FriendMapper;
import com.sharer.last.model.dto.friend.FriendChangeDTO;
import com.sharer.last.model.dto.friend.FriendQueryDTO;
import com.sharer.last.model.po.FriendPO;
import com.sharer.last.model.vo.friend.FriendVO;
import com.sharer.last.service.FriendService;
import com.sharer.last.utils.BeanUtil;
import com.sharer.last.wrapper.FriendWrapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 友链业务层实现
 *
 * @ClassName FriendServiceImpl
 * @Author wangjin
 * @Date 2023/5/5 20:44
 * @Description
 * @Version 1.0
 */
@Service
public class FriendServiceImpl extends ServiceImpl<FriendMapper, FriendPO> implements FriendService {
    @Resource
    FriendMapper friendMapper;

    @Resource
    FriendWrapper friendWrapper;

    private LambdaQueryWrapper<FriendPO> buildQueryWrapper(FriendQueryDTO queryDTO) {
        LambdaQueryWrapper<FriendPO> qw       = new LambdaQueryWrapper<>();
        String                       nickname = queryDTO.getNickname();
        if (StringUtil.isNotBlank(nickname)) {
            qw.like(FriendPO::getNickname, nickname);
        }
        return qw;
    }

    /**
     * 根据昵称查询数据
     *
     * @param nickname 昵称
     * @return
     */
    @Override
    public FriendPO getByNickname(String nickname) {
        LambdaQueryWrapper<FriendPO> qw = new LambdaQueryWrapper<>();
        qw.eq(FriendPO::getNickname, nickname);
        return this.getOne(qw, false);
    }

    /**
     * 根据id查询数据
     *
     * @param id
     * @return
     */
    @Override
    public FriendVO findById(Long id) {
        if (ConvertUtil.toInt(id) < 1) {
            throw new BusinessException(BusinessExceptionCode.ID_IS_NULL, ExceptionPrefixParamEnum.FRIEND);
        }
        FriendPO friendPO = this.getById(id);
        if (friendPO != null) {
            return friendWrapper.entityVO(friendPO);
        }
        return null;
    }


    /**
     * 分页查询
     *
     * @param queryDTO
     * @return
     */
    @Override
    public PageVO<FriendVO> selectListByPage(FriendQueryDTO queryDTO) {
        LambdaQueryWrapper<FriendPO> qw   = this.buildQueryWrapper(queryDTO);
        IPage<FriendPO>              page = this.page(QueryCondition.getPage(queryDTO.getPage()), qw);
        return friendWrapper.toPageVO(page);
    }

    /**
     * 查询所有友链
     *
     * @return
     */
    @Override
    public List<FriendVO> selectAllList() {
        LambdaQueryWrapper<FriendPO> qw = new LambdaQueryWrapper<>();
        qw.eq(FriendPO::getIsPublished, 1);
        List<FriendPO> list = this.list(qw);
        if (CollectionUtil.isNotEmpty(list)) {
            return friendWrapper.listVO(list);
        }
        return new ArrayList<>();
    }

    /**
     * 创建友链
     *
     * @param dto
     */
    @Override
    public void createFriend(FriendChangeDTO dto) {
        FriendPO friendPO = BeanUtil.copy(dto, FriendPO.class);
        if (!this.save(friendPO)) {
            throw new BusinessException(BusinessExceptionCode.DATA_INSERT_FAIL, ExceptionPrefixParamEnum.FRIEND);
        }
    }

    /**
     * 更新友链
     *
     * @param dto
     */
    @Override
    public void updateFriend(FriendChangeDTO dto) {
        Long id = dto.getId();
        if (ConvertUtil.toInt(id) < 1) {
            throw new BusinessException(BusinessExceptionCode.ID_IS_NULL, ExceptionPrefixParamEnum.FRIEND);
        }
        FriendPO friendPO = this.getById(id);
        if (friendPO == null) {
            throw new BusinessException(BusinessExceptionCode.DATA_IS_EMPTY, ExceptionPrefixParamEnum.FRIEND);
        }
        FriendPO friend = BeanUtil.copy(dto, FriendPO.class);
        if (!this.updateById(friend)) {
            throw new BusinessException(BusinessExceptionCode.DATA_UPDATE_FAIL, ExceptionPrefixParamEnum.FRIEND);
        }
    }

    /**
     * 更新友链访问次数
     *
     * @param id
     */
    @Override
    public void updateFriendViewsById(Long id) {
        if (ConvertUtil.toInt(id) < 1) {
            throw new BusinessException(BusinessExceptionCode.ID_IS_NULL, ExceptionPrefixParamEnum.FRIEND);
        }
        FriendPO friendPO = this.getById(id);
        if (friendPO == null) {
            throw new BusinessException(BusinessExceptionCode.DATA_IS_EMPTY, ExceptionPrefixParamEnum.FRIEND);
        }
        FriendPO friend = FriendPO.builder().id(id).views(friendPO.getViews() + 1).build();
        if (!this.updateById(friend)) {
            throw new BusinessException(BusinessExceptionCode.DATA_UPDATE_FAIL, ExceptionPrefixParamEnum.FRIEND);
        }
    }

    /**
     * 更新友链访问次数
     *
     * @param nickname 昵称
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateViewsByNickname(String nickname) {
        if (StringUtil.isBlank(nickname)) {
            throw new BusinessException(BusinessExceptionCode.NICKNAME_IS_BLANK, ExceptionPrefixParamEnum.FRIEND);
        }
        //判断友链是否存在
        FriendPO friendPO = this.getByNickname(nickname);
        if (friendPO == null) {
            throw new BusinessException(BusinessExceptionCode.DATA_IS_EMPTY, ExceptionPrefixParamEnum.FRIEND);
        }
        FriendPO friend = FriendPO.builder().id(friendPO.getId()).views(friendPO.getViews() + 1).build();
        if (!this.updateById(friend)) {
            throw new BusinessException(BusinessExceptionCode.DATA_UPDATE_FAIL, ExceptionPrefixParamEnum.FRIEND);
        }
    }

    /**
     * 更新友链是否显示
     *
     * @param id
     * @param published
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateFriendPublishedById(Long id, Integer published) {
        if (ConvertUtil.toInt(id) < 1) {
            throw new BusinessException(BusinessExceptionCode.ID_IS_NULL, ExceptionPrefixParamEnum.FRIEND);
        }
        FriendPO friendPO = this.getById(id);
        if (friendPO == null) {
            throw new BusinessException(BusinessExceptionCode.DATA_IS_EMPTY, ExceptionPrefixParamEnum.FRIEND);
        }
        FriendPO friend = FriendPO.builder().id(id)
                .isPublished(published)
                .build();
        if (!this.updateById(friend)) {
            throw new BusinessException(BusinessExceptionCode.DATA_UPDATE_FAIL, ExceptionPrefixParamEnum.FRIEND);
        }
    }

    /**
     * 根据id删除友链
     *
     * @param id
     */
    @Override
    public void removeFriendById(Long id) {
        if (ConvertUtil.toInt(id) < 1) {
            throw new BusinessException(BusinessExceptionCode.ID_IS_NULL, ExceptionPrefixParamEnum.FRIEND);
        }
        FriendPO friendPO = this.getById(id);
        if (friendPO == null) {
            throw new BusinessException(BusinessExceptionCode.DATA_IS_EMPTY, ExceptionPrefixParamEnum.FRIEND);
        }
        if (!this.removeById(id)) {
            throw new BusinessException(BusinessExceptionCode.DATA_REMOVE_FAIL, ExceptionPrefixParamEnum.FRIEND);
        }
    }
}
